#include "sessionfriendarea.h"
#include <QScrollBar> //滚动条
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QStyleOption>
#include <QPainter>
#include "model/data.h"
#include "debug.h"


SessionFriendArea::SessionFriendArea(QWidget *parent)
    : QScrollArea{parent}
{
    // 1.设置必要的属性
    // 设置这个属性才能开启滚动效果
    this->setWidgetResizable(true);
    // 设置滚动条相关样式
    this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width:2px;background-color:rgb(46,46,46)}");
    this->horizontalScrollBar()->setStyleSheet( "QScrollBar:horizontal {height :0px;}");
    this->setStyleSheet("QWidget {border:none;}");
    // 2. 创建container
    container = new QWidget();
    // 和中间栏设置的宽度一致
    container->setFixedWidth(210);

    // 3. 把container设置进QScrollArea内
    this->setWidget(container);

    // 4.给这个widget指定布局管理器，一边后续添加元素进去
    QVBoxLayout* layout = new QVBoxLayout();
    // 设置边距
    layout->setContentsMargins(0,0,0,0);
    // 元素之间距离
    layout->setSpacing(0);
    // 向上对齐
    layout->setAlignment(Qt::AlignTop);
    // 将layout这个布局管理器设置进container中
    container->setLayout(layout);

    // //4.简单测试一下滚动效果
    // for(int i = 0; i < 50; i++)
    // {
    //     QPushButton* btn = new QPushButton();
    //     btn->setText("按钮");
    //     btn->setStyleSheet("QPushButton { background-color: red; color: white; }");
    //     layout->addWidget(btn);
    // }



    // 构造出一些临时数据，作为界面调试依据，后续要删除掉

#if TEST_UI
    QIcon icon(":/resource/image/defaultAvatar.png");
    for(int i = 0; i < 30; i++)
    {
        this->addItem(SessionItemType,QString::number(i),icon,"张三"+QString::number(i),"最后一条消息" + QString::number(i));
    }
#endif


}


void SessionFriendArea::clear()
{

    QLayout* layout = container->layout();

    // 遍历布局管理器中的所有元素，并以此从布局管理器中删除元素
    for(int i = layout->count() - 1; i >= 0; i--)
    {
        QLayoutItem* item = layout->takeAt(i);
        // 别忘了还需要对该对象进行释放
        if(item->widget())
        {
            // 把这个一处的内容widget进行释放
            // 正常使用的时候，new出来的对象添加到布局管理器中
            delete item->widget();
        }
    }

}


// 当派生出3个子类item时，此时addItem不是SessionFriendItem,而是SessionItem,FriendItem,ApplyItem 其中的一个
void SessionFriendArea::addItem(ItemType itemType,const QString& id,const QIcon &avatar,
                                const QString &name, const QString &text)
{
    SessionFriendItem* item = nullptr;
    if(itemType == SessionItemType)
    {
        item =  new SessionItem(this,id,avatar,name,text);

    }
    else if(itemType == FriendItemType)
    {
        item =  new FriendItem(this,id,avatar,name,text);
    }
    else if(itemType == ApplyItemType)
    {
        item =  new ApplyItem(this,id,avatar,name);
    }
    else
    {
        LOG << "错误的 ItemType itemType = " << itemType;
        return;
    }
    // 将该item 添加到 container控键的布局管理器中
    container->layout()->addWidget(item);
}

void SessionFriendArea::clickItem(int index)
{
    if(index < 0 || index >= container->layout()->count())
    {
        LOG << "点击元素的下标, 超出范围 index = " << index;
        return;
    }
    QLayoutItem* layoutItem = container->layout()->itemAt(index);
    if(layoutItem == nullptr || layoutItem->widget() == nullptr)
    {
        LOG << "指定的元素不存在, index =  " << index;
    }
    SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(layoutItem->widget());
    item->select();
}

void SessionFriendItem::paintEvent(QPaintEvent *event)
{
    (void)event;
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);

}


///////////////////////////////
/// 滚动区域Item实现
////////////////////////////////
SessionFriendItem:: SessionFriendItem(QWidget* owner,const QIcon& avatar,const QString& name,const QString& text)
    :owner(owner)
{
    this->setFixedHeight(70);
    this->setStyleSheet("QWidget{background-color : rgb(220,220,220); }");
    // 创建网格布局管理器，管理 头像，名称，消息 这三个部分
    QGridLayout* layout = new QGridLayout();
    // 左上右下的间隔
    layout->setContentsMargins(10,0,0,0);
    // 给每个元素添加间隔
    //layout->setSpacing(10);
    // 将上述操作变为水平和垂直分开加间距
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(0);
    this->setLayout(layout);
    // 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(50,50);
    avatarBtn->setIconSize(QSize(50,50));
    avatarBtn->setIcon(avatar);
    avatarBtn->setStyleSheet("QPushButon {border:none;}");
    // 针对按钮尺寸的一个策略，期望是固定尺寸  水平，垂直
    avatarBtn->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    // 创建名字
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel{font-size:18px;font-weight:600; }");
    // 整个高度为70
    nameLabel->setFixedHeight(35);
    nameLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);


    // 消息预览的Label
    messageLabel = new QLabel();
    messageLabel->setText(text);
    messageLabel->setFixedHeight(35);
    messageLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
    // 头像处于0,0处，占2行2列
    layout->addWidget(avatarBtn,0,0,2,2);
    // 名字处于0,2处，占1行1列
    layout->addWidget(nameLabel,0,2,1,2);
    // 消息预览处于1,2处，占1行1列
    layout->addWidget(messageLabel,1,2,1,2);

}

void SessionFriendItem::mousePressEvent(QMouseEvent* event)
{
    // 鼠标点击时，触发这个函数
    // 某些控键存在信号槽 clicked 可以直接捕获鼠标信号
    // 对于没有该信号槽的类，可以重写 mousePressEvent 来捕获鼠标事件
    (void)event;
    select();

}

void SessionFriendItem::enterEvent(QEnterEvent *event)
{
    (void)event;
    // 如果当前是选中的，则返回
    if(this->selected)
    {
        return;
    }
    // 鼠标移动到Item区域，设置背景色
    this->setStyleSheet("QWidget{background-color : rgb(190,190,190); }");
}

void SessionFriendItem::leaveEvent(QEvent *event)
{
    (void)event;
    // 如果当前是选中的，则返回
    if(this->selected)
    {
        return;
    }
    // 鼠标离开Item区域， 还原背景色
    this->setStyleSheet("QWidget{background-color : rgb(220,220,220); }");

}

void SessionFriendItem::select()
{
    // 点击时，修改背景色，突显出点击的，当点击另外一个时，当前的恢复原样

    // 遍历其他元素，拿到所有兄弟元素
    const QObjectList children = this->parentWidget()->children();
    for(QObject* child : children)
    {
        if(!child->isWidgetType())
        {
            // 不是Widget 进行跳过
            continue;
        }
        // 是Widget，就把这里的child强转成 SessionFriendItem对象
        SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
        if(item->selected)
        {
            item->selected = false;
            item->setStyleSheet("QWidget{background-color : rgb(220,220,220); }");
        }
    }

    // 所以此处不仅仅要设置当前选中item的背景色，还要还原其他元素的背景色
    // 涉及到 selected
    this->setStyleSheet("QWidget{background-color : rgb(180,180,180); }");
    this->selected = true;

    // 调用active
    this->active();
}

void SessionFriendItem::active()
{
    // 父类的active
    // 父类中，我们并不需要去实现，而是要子类去重写该active
}

///////////////////////////////
///  会话Item的实现
////////////////////////////////

SessionItem::SessionItem(QWidget *owner, const QString &chatSessionID, const QIcon &avatar,
                         const QString &name, const QString &lastMessage)
    :SessionFriendItem(owner,avatar,name,lastMessage),chatSessionId(chatSessionID)
{

}

void SessionItem::active()
{
    // TODO 点击之后，要激活对应的会话列表
    LOG << "点击SessionItem触发的逻辑, chatSessionId" << chatSessionId;
}

///////////////////////////////
///  好友Item的实现
////////////////////////////////
FriendItem::FriendItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name, const QString &description)
    :SessionFriendItem(owner,avatar,name,description),userId(userId)
{

}

void FriendItem::active()
{
    // TODO 点击之后，要加载会话的历史消息列表
    LOG << "点击 FriendItem 触发的逻辑, userId" << userId;
}



///////////////////////////////
///  好友申请 Item的实现
////////////////////////////////
ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name)
    :SessionFriendItem(owner,avatar,name,""),userId(userId)
{
    //  需要添加 按钮， 同意，拒绝
    // 1. 将消息预览 messageLabel 在layout中移除 上面初始化中使用的是QGridLayout (SessionFriendItem这个构造函数中)
    // this->layout 拿到的是一个父类
    QGridLayout* layout = dynamic_cast<QGridLayout*>(this->layout());
    layout->removeWidget(messageLabel);
    //记得释放内存，否则内存泄漏
    delete messageLabel;

    // 2.添加按钮

    QPushButton* acceptBtn = new QPushButton();
    acceptBtn->setText("同意");
    QPushButton* rejectBtn = new QPushButton();
    rejectBtn->setText("拒绝");

    // 3.添加到布局管理器中
    // 添加到 第1行第2列，占据1行1列
    layout->addWidget(acceptBtn,1,2,1,1);
    layout->addWidget(rejectBtn,1,3,1,1);

}

void ApplyItem::active()
{
    // 这个函数不需要实现任何内容
    LOG << "点击 ApplyItem 触发的逻辑, userId" << userId;
}
